const path = require('path');
const fs = require('fs')
const request = require('request');
const zipdir = require('zip-dir');
const os = require('os');
const logger = require('./util/logger')
const plugin_name = 'send-zip-dir-webpack-plugin';

const defaultOpt = {
  name: 'archiver.zip',
  dir: '', // 需要打包的文件夹路径
  url: '', // 上传时接口url
  data: {}, // 上传时携带数据
  success: () => {}
}

class SendZipDirWebpackPlugin {
  constructor(options = {}) {
    this.options = {...defaultOpt, ...options};
    this.zipFilePath = path.join(os.tmpdir() || './', this.options.name)
    this.check()
  }
  apply(compiler) {
    const doneCallback = stats => {
      if(stats.hasErrors()){
        logger.warn(plugin_name + ': pausing due to webpack errors');
        return;
      }
      this.initSend()
    }
    if(compiler.hooks){
      compiler.hooks.done.tap(plugin_name, doneCallback);
    }else{
      compiler.plugin("done", doneCallback)
    }
  }
  check(){
    const { dir, url } = this.options
    if(!dir){
      throw new TypeError(plugin_name + ': options.dir is required')
    }
    if(!url){
      throw new TypeError(plugin_name + ': options.url is required')
    }
    return true
  }
  async initSend(){
    if(!this.check()){
      return;
    }
    const buffer = await this.pack()
    this.send(buffer)
    fs.unlinkSync(this.zipFilePath);
  }
  pack(){
    return new Promise((resolve, reject) => {
      zipdir(this.options.dir, { saveTo: this.zipFilePath },(err, buffer) => {
        if (err) {
          reject(err);
        }else{
          resolve(buffer);
        }
      });
    })
  }
  send() {
    const formData = {
      file: {
        value: fs.createReadStream(this.zipFilePath),
        options: {
          filename: this.options.name,
          contentType: 'application/octet-stream',
        },
      },
      data: JSON.stringify(this.options.data),
    };
    request({
      url: this.options.url,
      method: 'post',
      formData,
    }, (err, httpResponse, body) => {
        if (err) {
          logger.error(plugin_name + ': 上传失败 ');
          console.log(JSON.stringify(err));
          return;
        }
        try {
          body = JSON.parse(body);
          if (body.flag === 1) {
            this.options.success(body.data)
          } else {
            logger.error(plugin_name + ': 上传失败 ');
            logger.error(JSON.stringify(body));
          }
        } catch (e) {
          logger.error(plugin_name + ': 上传失败 ');
          logger.error(JSON.stringify(body));

        }
    });
  }
}

module.exports = SendZipDirWebpackPlugin;